/* 单线程-TCP服务端 */

/*
 * 该服务端无法实现与多个客户端进行交互----（使用多路转接IO可以）
*/

#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

using namespace std;

int main()
{   
    /* 1.创建侦听套接字
     * 2.绑定地址信息
     * 3.监听
     * */
    int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    if(listen_fd < 0)
    {
        perror("socket");
        return 0;
    }
    
    struct sockaddr_in ser_addr;
    ser_addr.sin_family = AF_INET;
    ser_addr.sin_port = htons(38989);
    ser_addr.sin_addr.s_addr = inet_addr("0.0.0.0");    //服务端的IP
    
    int ret = bind(listen_fd, (struct sockaddr*)&ser_addr, sizeof(ser_addr));
    if(ret < 0)
    {
        perror("bind");
        return 0;
    }

    ret = listen(listen_fd, 5);
    if(ret < 0)
    {
        perror("listen");
        return 0;
    }

    /* 循环处理
     * 4.获取新链接
     * 5.收发数据
     * */
    while(1)
    {
        struct sockaddr_in cli_addr;    //建立链接的对端（客户端）地址信息
        socklen_t cli_addr_len = sizeof(cli_addr);
        int new_sockfd = accept(listen_fd, (struct sockaddr*)&cli_addr, &cli_addr_len);
        if(new_sockfd < 0)
        {
            perror("accept");
            continue;
        }
        
        char buf[1024] = {0};
        ssize_t recv_size = recv(new_sockfd, buf, sizeof(buf) - 1, 0);    //收数据
        if(recv_size < 0)
        {
            perror("recv");
            continue;
        }
        else if(recv_size == 0)    //对端关闭
        {
            cout << "peer shutdown!" << endl;
            close(new_sockfd);
            continue;
        }
        printf("server <- client[%s:%d]:%s\n", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port), buf);

        memset(buf, '\0', sizeof(buf));
        sprintf(buf,"client <- server[%s:%d]:Get!\n", inet_ntoa(ser_addr.sin_addr), ntohs(ser_addr.sin_port));
        send(new_sockfd, buf, strlen(buf), 0);    //发数据
    }

    close(listen_fd);
    return 0;
}
